<?php

namespace app\api\controller\clockin;
use app\api\controller\develop\DatagridColumn;
use app\api\service\clockin\ClockinActivityPlanService;
use app\api\service\clockin\ClockinActivityUserService;
use app\api\service\develop\DatagridColumnService;
use app\api\service\log\AdminOperateLogService;
use app\api\service\user\UserClockinRecordService;
use app\api\service\user\UserService;
use app\BaseController;
use app\api\service\clockin\ClockinActivityService;
use app\util\AdminUserUtil;
use app\util\CommonUtil;
use app\util\DateUtil;
use app\util\ResponseUtil;
use app\util\UserUtil;

class ClockinActivity extends BaseController
{
    private $arrFieldTitle = array("activity_name" => "活动名称", "start_time"=>"活动开始时间", "end_time"=>"活动结束时间", "join_start_time"=>"报名开启时间", "status" => "状态");

    public function getClockinActivityInfo()
    {
        $id = $this->requestData['id'];
        $service = new ClockinActivityService();
        $finalData = $service->findRowById($id);
        return ResponseUtil::success($finalData);
    }

    public function getClockinActivityList()
    {
        $pageIndex = $this->requestData['page'];
        $pageSize = $this->requestData['rows'];
        $service = new ClockinActivityService();
        $list = $service->getListWithPage($this->requestData, $pageIndex, $pageSize);
        $total = $service->getTotalNum($this->requestData);
        $finalData = CommonUtil::getPaginationData($list, $total);
        return ResponseUtil::success($finalData);
    }

    public function getClockinActivityOption()
    {
        $service = new ClockinActivityService();
        $list = $service->getListNoPage($this->requestData);
        return ResponseUtil::success($list);
    }

    public function addClockinActivity()
    {
        try{
            if(empty($this->requestData['datagrid_code'])){
                return ResponseUtil::failure("数据表标识码不可为空");
            }
            $datagridCode = $this->requestData['datagrid_code'];

            $serviceDatagridColumn = new DatagridColumnService();
            $columnList = $serviceDatagridColumn->getListNoPage(['datagrid_code' => $datagridCode, 'is_in_add'=>1, 'is_require' => 1]);
            foreach($columnList as $columnItem){
                if(empty($this->requestData[$columnItem['column_name']])){
                    return ResponseUtil::failure($columnItem['column_title']."不可为空");
                }
            }
            if($this->requestData['start_time'] < $this->requestData['join_start_time']){
                return ResponseUtil::failure("报名开启时间不可在活动开始时间之后");
            }

            if($this->requestData['end_time'] < $this->requestData['start_time']){
                return ResponseUtil::failure("活动结束时间不可大于活动开始时间");
            }

            $service = new ClockinActivityService();
            $res = $service->createRow($this->requestData);
            if($res){
                $addInfo = CommonUtil::getDataInsertMessage($res, $this->arrFieldTitle);
                $message = '新增打卡活动';
                if($addInfo){
                    $message .= ','.$addInfo;
                }
                $logData = [
                    'subject_id' => $res,
                    'remark'  => '',
                    'description' => $message,
                ];
                AdminUserUtil::addOperateLog('ClockinActivity', AdminOperateLogService::ARR_ACTION_TYPE['add'], $logData);
                return ResponseUtil::success($res);
            }else{
                return ResponseUtil::failure("新增打卡活动失败");
            }
        }catch(\Exception $e){
            CommonUtil::addErrorLog(__CLASS__, __FUNCTION__,  CommonUtil::getExceptionMessage($e));
            return ResponseUtil::failure("新增打卡活动失败");
        }
    }

    public function editClockinActivity()
    {
        try{
            if(empty($this->requestData['id'])){
                return ResponseUtil::failure("请指定要编辑的打卡活动");
            }
            $datagridCode = $this->requestData['datagrid_code'];

            $serviceDatagridColumn = new DatagridColumnService();
            $columnList = $serviceDatagridColumn->getListNoPage(['datagrid_code' => $datagridCode, 'is_in_add'=>1, 'is_require' => 1]);
            foreach($columnList as $columnItem){
                if(empty($this->requestData[$columnItem['column_name']])){
                    return ResponseUtil::failure($columnItem['column_title']."不可为空");
                }
            }
            if($this->requestData['start_time'] < $this->requestData['join_start_time']){
                return ResponseUtil::failure("报名开启时间不可在活动开始时间之后");
            }

            if($this->requestData['end_time'] < $this->requestData['start_time']){
                return ResponseUtil::failure("活动结束时间不可大于活动开始时间");
            }

            $id = $this->requestData['id'];
            $service = new ClockinActivityService();
            $oldInfo = $service->findRowById($id);
            if(empty($oldInfo)){
                return ResponseUtil::failure("打卡活动不存在");
            }
            $res = $service->updateRowById($id, $this->requestData);
            if($res){
                $changeInfo = CommonUtil::getChangeData($oldInfo, $this->requestData, $this->arrFieldTitle);
                $message = '编辑打卡活动';
                if($changeInfo){
                    $message .= ','.$changeInfo['update_info'];
                }
                $logData = [
                    'subject_id' => $id,
                    'remark'  => $oldInfo['activity_name'],
                    'description' => $message,
                ];
                AdminUserUtil::addOperateLog('ClockinActivity', AdminOperateLogService::ARR_ACTION_TYPE['edit'], $logData);
                return ResponseUtil::success();
            }else{
                return ResponseUtil::failure("编辑打卡活动失败");
            }
        }catch(\Exception $e){
            CommonUtil::addErrorLog(__CLASS__, __FUNCTION__,  CommonUtil::getExceptionMessage($e));
            return ResponseUtil::failure("编辑打卡活动失败");
        }
    }

    /**
     * 删除打卡活动
     * 已经有用户加入的，不可删除
     * @return \think\response\Json
     */
    public function deleteClockinActivity()
    {
        try{
            $id = $this->requestData['id'];
            $service = new ClockinActivityService();
            $info = $service->findRowById($id);
            if(!$info){
                return ResponseUtil::failure("数据不存在");
            }

            

            $res = $service->removeRowById($id);
            if($res){
                $deleteInfo = CommonUtil::getDataDeleteMessage($info, $this->arrFieldTitle);
                $message = '删除打卡活动';
                if($deleteInfo){
                    $message .= ','.$deleteInfo;
                }
                $logData = [
                    'subject_id' => $id,
                    'remark'  => '',
                    'description' => $message,
                ];
                AdminUserUtil::addOperateLog('ClockinActivity', AdminOperateLogService::ARR_ACTION_TYPE['delete'], $logData);
                return ResponseUtil::success();
            }else{
                return ResponseUtil::failure("删除打卡活动失败");
            }
        }catch(\Exception $e){
            CommonUtil::addErrorLog(__CLASS__, __FUNCTION__,  CommonUtil::getExceptionMessage($e));
            return ResponseUtil::failure("删除打卡活动失败");
        }
    }



    public function getRecentClockinActivityList()
    {
        $service = new ClockinActivityService();
        $list = $service->getRecentList();
        return ResponseUtil::success($list);
    }

    public function onShelfClockinActivity()
    {
        try{
            if(empty($this->requestData['id'])){
                return ResponseUtil::failure("请指定要上架的打卡活动");
            }

            $id = $this->requestData['id'];
            $service = new ClockinActivityService();
            $oldInfo = $service->findRowById($id);
            if(empty($oldInfo)){
                return ResponseUtil::failure("打卡活动不存在");
            }
            if($service::ARR_ACTIVITY_STATUS['on_shelf'] == $oldInfo['status']){
                return ResponseUtil::failure("该打卡活动已上架");
            }

            $updateData = array('status' => $service::ARR_ACTIVITY_STATUS['on_shelf']);
            $res = $service->updateRowById($id, $updateData);
            if($res){
                $message = '打卡活动上架,[<b>活动名称</b>]:'.$oldInfo['activity_name'];
                $logData = [
                    'subject_id' => $id,
                    'remark'     => '',
                    'description' => $message,
                ];
                AdminUserUtil::addOperateLog('ClockinActivity', AdminOperateLogService::ARR_ACTION_TYPE['edit'], $logData);
                return ResponseUtil::success();
            }else{
                return ResponseUtil::failure("打卡活动上架失败");
            }
        }catch(\Exception $e){
            CommonUtil::addErrorLog(__CLASS__, __FUNCTION__,  CommonUtil::getExceptionMessage($e));
            return ResponseUtil::failure("打卡活动上架失败");
        }
    }

    /**
     * 活动下架
     * 如果用户已加入，不可直接下架
     * @return \think\response\Json
     */
    public function offShelfClockinActivity()
    {
        try{
            if(empty($this->requestData['id'])){
                return ResponseUtil::failure("请指定要下架的打卡活动");
            }

            $id = $this->requestData['id'];
            $service = new ClockinActivityService();
            $oldInfo = $service->findRowById($id);
            if(empty($oldInfo)){
                return ResponseUtil::failure("打卡活动不存在");
            }
            if($service::ARR_ACTIVITY_STATUS['new'] == $oldInfo['status']){
                return ResponseUtil::failure("该打卡活动未上架，无需下架");
            }

            if($service::ARR_ACTIVITY_STATUS['off_shelf'] == $oldInfo['status']){
                return ResponseUtil::failure("该打卡活动已下架");
            }
            $updateData = array('status' => $service::ARR_ACTIVITY_STATUS['off_shelf']);
            $res = $service->updateRowById($id, $updateData);
            if($res){
                $message = '打卡活动下架,[<b>活动名称</b>]:'.$oldInfo['activity_name'];
                $logData = [
                    'subject_id' => $id,
                    'remark'     => '',
                    'description' => $message,
                ];
                AdminUserUtil::addOperateLog('ClockinActivity', AdminOperateLogService::ARR_ACTION_TYPE['edit'], $logData);
                return ResponseUtil::success();
            }else{
                return ResponseUtil::failure("打卡活动下架失败");
            }
        }catch(\Exception $e){
            CommonUtil::addErrorLog(__CLASS__, __FUNCTION__,  CommonUtil::getExceptionMessage($e));
            return ResponseUtil::failure("打卡活动下架失败");
        }
    }

    public function getClockinActivityDateList()
    {
        try{
            $clockinActivityId = $this->requestData['clockin_activity_id'];
            if(empty($clockinActivityId)){
                return ResponseUtil::failure("请指定打卡活动");
            }

            $clockinActivityService = new ClockinActivityService();
            $activityInfo = $clockinActivityService->findRowById($clockinActivityId);
            if(empty($activityInfo)){
                return ResponseUtil::failure("打卡活动不存在");
            }

            $dateList = $clockinActivityService->getClockinActivityDateList($activityInfo, true);
            return ResponseUtil::success($dateList);
        }catch (\Exception $e){
            CommonUtil::addErrorLog(__CLASS__, __FUNCTION__,  CommonUtil::getExceptionMessage($e));
            return ResponseUtil::failure("日期列表获取失败");
        }
    }

    /**
     * 报名活动
     */
    public function joinClockinActivity()
    {
        try{
            $clockinActivityId = $this->requestData['id'];
            if(empty($clockinActivityId)){
                return ResponseUtil::failure("请指定打卡活动");
            }

            $clockinActivityService = new ClockinActivityService();
            $activityInfo = $clockinActivityService->findRowById($clockinActivityId);
            if(empty($activityInfo)){
                return ResponseUtil::failure("打卡活动不存在");
            }

            $currentTime = DateUtil::getCurrentDatetime();
            if($currentTime < $activityInfo['join_start_time']){
                return ResponseUtil::failure("活动报名时间还未开始");
            }

            if(empty($this->requestData['arr_user_code'])){
                return ResponseUtil::failure("请选择报名用户");
            }

            if(!is_array($this->requestData['arr_user_code'])){
                return ResponseUtil::failure("参数格式有误");
            }

            $clockinActivityUserService = new ClockinActivityUserService();
            $arrUserCode = $this->requestData['arr_user_code'];
            $nowTime = DateUtil::getCurrentDatetime();
            $count = 0;
            foreach($arrUserCode as $userCode){
                $addData = array(
                    'clockin_activity_id' => $clockinActivityId,
                    'user_code' => $userCode,
                    'update_time' => $nowTime
                );
                $res = $clockinActivityUserService->createRow($addData);
                if($res){
                    $count++;
                }
            }
            if($count != count($arrUserCode)){
                return ResponseUtil::failure("加入打卡活动失败");
            }else{
                return ResponseUtil::success();
            }
        }catch (\Exception $e){
            CommonUtil::addErrorLog(__CLASS__, __FUNCTION__,  CommonUtil::getExceptionMessage($e));
            return ResponseUtil::failure("加入打卡活动失败");
        }
    }

    /**
     * Desc: 后台帮助用户打卡
     * @return \think\response\Json
     * Datetime: 2024/11/21 8:23 by zdb
     */
    public function helpUserClockin()
    {
        try{
            $planDate = $this->requestData['plan_date'];
            if(empty($planDate)){
                return ResponseUtil::failure("请指定计划日期");
            }

            $clockinActivityId= $this->requestData['clockin_activity_id'];
            if(empty($clockinActivityId)){
                return ResponseUtil::failure("请指定活动");
            }

            $clockinActivityService = new ClockinActivityService();
            $clockinActivityInfo = $clockinActivityService->findRowById($clockinActivityId);
            if(empty($clockinActivityInfo)){
                return ResponseUtil::failure("活动不存在");
            }

            $clockinActivityPlanService = new ClockinActivityPlanService();
            $planCondition = array(
                'plan_date' => $planDate,
                'clockin_activity_id' => $clockinActivityId
            );
            $clockinActivityPlanInfo = $clockinActivityPlanService->findRowByData($planCondition);
            if(empty($clockinActivityPlanInfo)){
                return ResponseUtil::failure("打卡计划不存在");
            }

            $arrUserId = $this->requestData['arr_user_id'];
            if(empty($arrUserId)){
                return ResponseUtil::failure("请选择打卡用户");
            }

            //必须先确保用户都是已经报名参加了活动的用户
            $clockinActivityUserService = new ClockinActivityUserService();
            $activityUserList = $clockinActivityUserService->getListNoPage(array('clockin_activity_id'=>$clockinActivityId,  'arr_user_id' => $arrUserId));
            if(count($activityUserList) != count($arrUserId)){
                return ResponseUtil::failure("部分用户没有报名活动");
            }

            $userClockinRecordService = new UserClockinRecordService();
            $res = $userClockinRecordService->createManyRowOneByOne(array($clockinActivityPlanInfo['id']), $arrUserId);
            if($res){
                return ResponseUtil::success();
            }else{
                $arrFailUserId = array_column($res, 'user_id');
                $serviceUser = new UserService();
                $userList = $serviceUser->getListNoPage(array('arr_user_id' => $arrFailUserId));
                $columnUserAccount = array_column($userList, 'account');
                return ResponseUtil::failure("打卡失败,用户".implode(",", $columnUserAccount)."打卡不成功");
            }
        }catch (\Exception $e){
            CommonUtil::addErrorLog(__CLASS__, __FUNCTION__,  CommonUtil::getExceptionMessage($e));
            return ResponseUtil::failure("打卡失败");
        }
    }
}



